# 核心数据：居民家庭收入调查数据（八大类，消费转换矩阵）
# 左边分为70个行业，可不可以是20个行业
# 蓝色为每个行业的出口
# 绿色为进口的东西
# 一张图把国民经济看出来
# 这个图的假定
# 看到这个样子
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import gradio as gr

from copy import deepcopy

def get_consume_data():
    data = pd.read_excel('十等分平均值.xlsx',index_col=0, sheet_name='十等分消费占比')
    h_consume = 347363 # 2018年居民消费
    g_consume = 148406 # 2018年政府消费
    g_data = deepcopy(data)
    g_data.iloc[:,0] = 0.1
    data = h_consume * data
    g_data = g_consume * g_data
    data = data.round(2)
    g_data = g_data.round(2)
    df = pd.concat([data,g_data],axis=1)
    df.columns = ['居民消费','政府消费']
    return df

def get_import_export():
    data = pd.read_excel('2018年投入产出表.xlsx',index_col=0, sheet_name='进出口')
    data_153_to_70 = pd.read_excel('2018年投入产出表.xlsx',index_col=0, sheet_name='153to70')
    dic_153_to_70 = data_153_to_70.iloc[:,0].to_dict()
    
    meta_dic_70_153 = {}
    for k,v in dic_153_to_70.items():
        if v not in meta_dic_70_153.keys():
            meta_dic_70_153[v] = [k]
        else:
            meta_dic_70_153[v].append(k)
    
    for k, li in meta_dic_70_153.items():
        print(k,li)
        temp = data.loc[li].sum()
        for i in li:
            data.drop(i, inplace=True, axis=0)
        data.loc[k,:] = temp
    data = data / 10000
    data = data.round(2)
    return data

class LongTermGrowthSpace:
    def __init__(self,vas,K,Inv):
        self.vas = vas
        self.K = K
        self.Inv = Inv
    
    @staticmethod
    def loc_year(df, year):
        if not isinstance(df.index, pd.DatetimeIndex):
            df.index = pd.to_datetime(df.index)
        return df.loc[df.index.year == year]


class ShowData:
    def __init__(self):
        vas = pd.read_excel('生产法增加值_70行业.xlsx',index_col=0)
        K = pd.read_excel('资本存量_70行业.xlsx',index_col=0)
        Inv = pd.read_excel('GFCI_70行业.xlsx',index_col=0)
        lgs = LongTermGrowthSpace(vas,K,Inv)
        vas_2018 = lgs.loc_year(vas,2018).sum()[1:]
        k_2018 = lgs.loc_year(K,2018).sum()[1:]
        inv_2018 = lgs.loc_year(Inv,2018).sum()[1:]
        import_export = get_import_export()
        self.vas = vas_2018
        self.K = k_2018
        self.Inv = inv_2018
        self.import_export = import_export
        self.consumption = get_consume_data()
        self.ex_im = ['出口','进口']
        self.vas_k = ['增加值','资本存量']
        self.color_dic = {'增加值':'purple','资本存量':'purple', '进口':'green','出口':'blue'}
        self.text_to_id = {s:str(i) for i, s in enumerate(self.vas.index.to_list())}
        self.height = 400
        self.width = 400

    def plot_consumption(self, show_ind):
        print(show_ind)
        categories = self.consumption.index.to_list()
        values_h = self.consumption['居民消费'].to_list()
        values_g = self.consumption['政府消费'].to_list()
        h_hover_text = [f'{c}:{v:.1f}亿元' for c, v in zip(categories, values_h)]
        g_hover_text = [f'{c}:{v:.1f}亿元' for c, v in zip(categories, values_g)]
        fig = go.Figure(data=[
            go.Bar(name='政府消费', x=categories, y=values_g, marker_color='blue',hovertext=g_hover_text),
            go.Bar(name='居民消费', x=categories, y=values_h, marker_color='orange',hovertext=h_hover_text),
        ])
        fig.update_layout(
            title='居民消费+政府消费',
            barmode='stack',  # 设置为堆叠模式
            legend=dict(x=0.5,y=1,xanchor='center',yanchor='bottom'),
            font=dict(family='Arial', size=12, color='black'),
            margin=dict(l=5, r=5, t=5, b=5),
            height=self.height,
            width=self.width,
        )
        return fig

    def plot_import_export(self, choose, show_ind):
        categories = self.import_export.index.to_list()
        values = self.import_export[choose].to_list()
        hov = [f'{c}:{v:.1f}亿元' for c, v in zip(categories, values)]
        if not show_ind:
            categories = [self.text_to_id[c] for c in categories]
    
        fig = go.Figure(data=[go.Bar(y=categories, x=values, orientation='h',hovertext=hov,
                                     marker_color=self.color_dic[choose])])
        fig.update_layout(title='进出口',font=dict(family='Arial', size=12, color='black'),
                          margin=dict(l=5, r=5, t=5, b=5),
                          height=self.height, width=self.width)
        fig.update_xaxes(side='top',autorange='reversed')
        fig.update_yaxes(side='right',autorange='reversed')
        return fig, self.import_export[choose]
    
    def plot_vas_k(self, choose, show_ind):
        dic = {'增加值':self.vas,'资本存量':self.K}
        categories = dic[choose].index.to_list()[::-1]
        values = dic[choose].to_list()[::-1]
        hov = [f'{c}:{v:.1f}亿元' for c, v in zip(categories, values)]
        if not show_ind:
            categories = [self.text_to_id[c] for c in categories]
        
        fig = go.Figure(data=[go.Bar(y=categories, x=values, orientation='h',
                                     hovertext=hov, marker_color=self.color_dic[choose])])
        fig.update_layout(
            title='生产法GDP/资本存量',
            height=self.height,
            font=dict(family='Arial', size=12, color='black'),
            margin=dict(l=5, r=5, t=5, b=5),
            width=self.width,
        )
        fig.update_xaxes(side='top')
        return fig, dic[choose]

    def plot_all(self, show_ind, ex_im, vas_k, height_img):
        print('>>>> >>>>',show_ind, ex_im, vas_k)
        self.height = height_img
        vas_k_fig, vas_k_se = self.plot_vas_k(vas_k, show_ind)
        ex_im_fig, ex_im_se = self.plot_import_export(ex_im, show_ind)
        con = self.plot_consumption('-')
        return vas_k_fig, ex_im_fig, con, self.df_to_text(ex_im_se), self.df_to_text(vas_k_se)


    @staticmethod
    def df_to_text(se):
        text = ''
        dic = deepcopy(se).sort_values(ascending=False).to_dict()
        for k, v in dic.items():
            add = f'{k}{v:.1f}亿元\n'
            text += add
        return text


    def html(self):
        with gr.Blocks() as demo:
            gr.Markdown("# 长期增长空间图")
            with gr.Row():
                with gr.Column(scale=1):
                    ex_im = gr.Dropdown(label='进出口', choices=self.ex_im, value=self.ex_im[0])
                with gr.Column(scale=1):
                    show_ind = gr.Checkbox(label='是显示行业', value=False)
                    height_img = gr.Slider(label='高度', minimum=400, maximum=1000, step=100, value=800)
                with gr.Column(scale=1):
                    vas_k = gr.Dropdown(label='Vas/K', choices=self.vas_k, value=self.vas_k[0])
            
            with gr.Row():
                with gr.Column(scale=1):
                    plot_ex_im = gr.Plot()
                with gr.Column(scale=1):
                    plot_cons = gr.Plot()
                with gr.Column(scale=1):
                    plot_vas_k = gr.Plot()
            
            gr.Markdown("# 数据")
            gr.Markdown("- 进出口采用2018年投入产出表数据，将153行业合并为70行业，增加值和资本存量采用全口径数据表2018年数据，消费十等分来自于CHIP数据，按照比例乘以2018年投入产出表，居民消费和政府消费")    
            with gr.Row():
                with gr.Column(scale=1):
                    left_text = gr.Textbox(label='进出口数据', value='-')
                with gr.Column(scale=1):
                    right_text = gr.Textbox(label='增加值资本存量', value='-')

            gr.on(triggers=[ex_im.change, vas_k.change, show_ind.change, height_img.change],
                  fn=self.plot_all,
                  inputs=[show_ind, ex_im, vas_k, height_img],
                  outputs=[plot_vas_k, plot_ex_im, plot_cons, left_text, right_text])

            # ex_im.change(
            #     self.plot_all, 
            #     inputs=[show_ind, ex_im, vas_k, height_img], 
            #     outputs=[plot_vas_k, plot_ex_im, plot_cons, left_text, right_text])
            # vas_k.change(
            #     self.plot_all, 
            #     inputs=[show_ind, ex_im, vas_k, height_img], 
            #     outputs=[plot_vas_k, plot_ex_im, plot_cons, left_text, right_text])
            # show_ind.change(
            #     self.plot_all, 
            #     inputs=[show_ind, ex_im, vas_k, height_img], 
            #     outputs=[plot_vas_k, plot_ex_im, plot_cons])

        return demo
    

sd = ShowData()
sd.html().launch()